<?php

namespace Rjyst\RjPdf\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\File;

class InstallCommand extends Command
{
    protected $signature = 'rj-pdf:install {--force : Force install without confirmation} {--skip-seed : Skip running seeders}';
    protected $description = 'Install RjYst PDF Package';

    public function handle()
    {
        $this->info('🚀 开始安装 RjYst PDF 扩展包...');

        // 1. 检查依赖扩展包
        if (!$this->checkDependencies()) {
            return;
        }

        // 2. 发布并检查迁移文件
        $this->publishMigrations();

        // 3. 发布模型文件
        $this->publishModels();

        // 4. 发布管理后台文件
        $this->publishAdminFiles();

        // 5. 发布 Seeders
        $this->publishSeeders();

        // 6. 更新数据库配置
        $this->updateDatabaseConfig();

        // 7. 更新 Category 模型
        $this->updateCategoryModel();

        // 8. 添加路由
        $this->addRoute();

        // 9. 自动执行 Seeders
        if (!$this->option('skip-seed')) {
            $this->runSeeders();
        }

        $this->info('🎉 RjYst PDF 扩展包安装完成！');
        $this->showNextSteps();
    }

    protected function checkDependencies()
    {
        $this->info('检查依赖扩展包...');

        $dependencies = [
            'App\Models\Category\Category' => [
                'name' => '意识听年级管理扩展包',
                'install_command' => 'php artisan category:install'
            ],
            'App\Models\Data\ClickLearn' => [
                'name' => '意识听点读数据扩展包',
                'install_command' => 'php artisan click-learn:install'
            ]
        ];

        $missingDependencies = [];

        foreach ($dependencies as $class => $info) {
            if (!class_exists($class)) {
                $this->error("❌ 缺少依赖: {$info['name']}");
                $this->line("请先运行: {$info['install_command']}");
                $missingDependencies[] = $info['name'];
            } else {
                $this->info("✅ 依赖检查通过: {$info['name']}");
            }
        }

        if (!empty($missingDependencies)) {
            $this->error('请先安装依赖扩展包后再继续！');
            return false;
        }

        return true;
    }

    protected function publishMigrations()
    {
        $this->info('发布迁移文件...');

        $this->call('vendor:publish', ['--tag' => 'rj-pdf-migrations']);

        // 检查表是否存在，不存在则运行迁移
        $migrations = [
            'pdf_images' => '2025_09_17_032019_create_pdf_images_table.php',
            'pdf_image_coordinates' => '2025_09_17_032110_create_pdf_image_coordinates_table.php',
            'textbook_reads' => '2025_09_17_093315_create_textbook_reads_table.php',
        ];

        foreach ($migrations as $table => $filename) {
            if (!Schema::hasTable($table)) {
                $this->info("{$table} 表不存在，正在创建...");
                $this->runSpecificMigration($filename);
            } else {
                $this->info("✅ {$table} 表已存在");
            }
        }
    }

    protected function runSpecificMigration($filename)
    {
        try {
            Artisan::call('migrate', ['--path' => 'database/migrations/' . $filename]);
            $this->info("✅ {$filename} 迁移完成");
        } catch (\Exception $e) {
            $this->error("迁移失败: " . $e->getMessage());
        }
    }

    protected function publishModels()
    {
        $this->info('发布模型文件...');

        $this->call('vendor:publish', ['--tag' => 'rj-pdf-models']);

        // 检查模型是否存在
        $models = [
            'PdfImage' => app_path('Models/Pdf/PdfImage.php'),
            'PdfImageCoordinate' => app_path('Models/Pdf/PdfImageCoordinate.php'),
            'TextbookRead' => app_path('Models/Pdf/TextbookRead.php'),
        ];

        foreach ($models as $name => $path) {
            if (File::exists($path)) {
                $this->info("✅ {$name} 模型已存在，跳过");
            } else {
                $this->info("✅ {$name} 模型创建完成");
            }
        }
    }

    protected function publishAdminFiles()
    {
        $this->info('发布管理后台文件...');

        // 发布控制器
        $this->call('vendor:publish', ['--tag' => 'rj-pdf-controllers']);

        // 发布仓库
        $this->call('vendor:publish', ['--tag' => 'rj-pdf-repositories']);

        // 检查管理后台文件是否存在
        $files = [
            'PdfImageController' => app_path('Admin/Controllers/Pdf/PdfImageController.php'),
            'PdfImage Repository' => app_path('Admin/Repositories/Pdf/PdfImage.php'),
        ];

        foreach ($files as $name => $path) {
            if (File::exists($path)) {
                $this->info("✅ {$name} 已存在，跳过");
            } else {
                $this->info("✅ {$name} 创建完成");
            }
        }
    }

    protected function publishSeeders()
    {
        $this->info('发布 Seeder 文件...');

        $this->call('vendor:publish', ['--tag' => 'rj-pdf-seeders']);

        $seeders = [
            'PdfMenuSeeder.php' => database_path('seeders/PdfMenuSeeder.php'),
            'PdfDataSeeder.php' => database_path('seeders/PdfDataSeeder.php'),
            'TextBookReadDataSeeder.php' => database_path('seeders/TextBookReadDataSeeder.php'),
        ];

        foreach ($seeders as $name => $path) {
            if (File::exists($path)) {
                $this->info("✅ {$name} 已存在，跳过");
            } else {
                $this->info("✅ {$name} 创建完成");
            }
        }
    }

    protected function updateDatabaseConfig()
    {
        $this->info('更新数据库配置...');

        $configPath = config_path('database.php');

        if (!File::exists($configPath)) {
            $this->warn('⚠️  database.php 配置文件不存在');
            return;
        }

        $content = File::get($configPath);

        // 检查是否已包含 zjmysql 配置
        if (strpos($content, "'zjmysql'") !== false) {
            $this->info('✅ zjmysql 数据库配置已存在');
            return;
        }

        // 在 rjmysql 配置后添加 zjmysql 配置
        $zjmysqlConfig = "        'zjmysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE_ZJ', 'forge'),
            'username' => env('DB_USERNAME_ZJ', 'forge'),
            'password' => env('DB_PASSWORD_ZJ', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],";

        // 查找 connections 数组中的位置
        if (preg_match("/'rjmysql'\s*=>\s*\[.*?\],/s", $content, $matches, PREG_OFFSET_CAPTURE)) {
            $insertPosition = $matches[0][1] + strlen($matches[0][0]);
            $content = substr_replace($content, "\n{$zjmysqlConfig}", $insertPosition, 0);

            File::put($configPath, $content);
            $this->info('✅ zjmysql 数据库配置添加完成');
        } else {
            $this->warn('⚠️  无法自动添加 zjmysql 配置，请手动添加');
        }
    }

    /**
     * 更新 Category 模型，添加 PdfImage 关联关系
     */
    protected function updateCategoryModel()
    {
        $this->info('检查并更新 Category 模型关联关系...');

        $categoryModelPath = app_path('Models/Category/Category.php');

        if (!File::exists($categoryModelPath)) {
            $this->error('❌ Category 模型文件不存在: ' . $categoryModelPath);
            return false;
        }

        $content = File::get($categoryModelPath);

        // 检查是否需要添加 use 语句
        $needsUseStatement = !$this->hasUseStatement($content, 'App\Models\Pdf\PdfImage');

        // 检查是否需要添加关联方法
        $needsRelationMethod = !$this->hasRelationMethod($content, 'PdfImage');

        if (!$needsUseStatement && !$needsRelationMethod) {
            $this->info('✅ Category 模型已包含 PdfImage 关联关系');
            return true;
        }

        // 添加 use 语句
        if ($needsUseStatement) {
            $content = $this->addUseStatement($content, 'App\Models\Pdf\PdfImage');
            $this->info('✅ 已添加 PdfImage use 语句');
        }

        // 添加关联方法
        if ($needsRelationMethod) {
            $content = $this->addRelationMethod($content, 'PdfImage', 'hasMany', 'PdfImage::class');
            $this->info('✅ 已添加 PdfImage 关联方法');
        }

        // 写入文件
        File::put($categoryModelPath, $content);
        $this->info('✅ Category 模型更新完成');

        return true;
    }

    /**
     * 检查是否已有指定的 use 语句
     */
    protected function hasUseStatement($content, $useClass)
    {
        return strpos($content, "use {$useClass};") !== false;
    }

    /**
     * 检查是否已有指定的关联方法
     */
    protected function hasRelationMethod($content, $methodName)
    {
        $patterns = [
            "/public\s+function\s+{$methodName}\s*\(\)/",
            "/function\s+{$methodName}\s*\(\)/"
        ];

        foreach ($patterns as $pattern) {
            if (preg_match($pattern, $content)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 添加 use 语句
     */
    protected function addUseStatement($content, $useClass)
    {
        $useStatement = "use {$useClass};";

        // 查找其他 use 语句的位置
        if (preg_match_all('/^use\s+[^;]+;$/m', $content, $matches, PREG_OFFSET_CAPTURE)) {
            // 在最后一个 use 语句后添加
            $lastUseMatch = end($matches[0]);
            $lastUsePosition = $lastUseMatch[1] + strlen($lastUseMatch[0]);

            $content = substr_replace($content, "\n{$useStatement}", $lastUsePosition, 0);
        }

        return $content;
    }

    /**
     * 添加关联方法
     */
    protected function addRelationMethod($content, $methodName, $relationType, $model)
    {
        $relationMethod = "    public function {$methodName}(): Relations\\HasMany
    {
        return \$this->{$relationType}({$model});
    }";

        // 查找类的结束位置（最后一个大括号前）
        $lastBracePos = strrpos($content, '}');

        if ($lastBracePos !== false) {
            // 在最后一个大括号前添加关联方法
            $beforeBrace = substr($content, 0, $lastBracePos);
            $afterBrace = substr($content, $lastBracePos);

            $content = rtrim($beforeBrace) . "\n\n" . $relationMethod . "\n" . $afterBrace;
        }

        return $content;
    }

    protected function addRoute()
    {
        $this->info('添加路由...');

        $routeFile = app_path('Admin/routes.php');
        $routeLine = "    \$router->resource('pdfImage', 'Pdf\\PdfImageController');";

        if (!File::exists($routeFile)) {
            $this->warn('⚠️  Admin routes.php 文件不存在，请手动添加路由');
            return;
        }

        $content = File::get($routeFile);

        // 检查路由是否已存在
        if (strpos($content, "pdfImage") !== false) {
            $this->info('✅ 路由已存在');
            return;
        }

        // 查找 }); 的位置，在其前面添加路由
        $closingPattern = '});';
        $position = strrpos($content, $closingPattern);

        if ($position !== false) {
            // 在 }); 前面添加新路由
            $beforeClosing = substr($content, 0, $position);
            $afterClosing = substr($content, $position);

            // 确保有适当的换行
            $newContent = rtrim($beforeClosing) . "\n" . $routeLine . "\n\n" . $afterClosing;

            File::put($routeFile, $newContent);
            $this->info('✅ 路由添加完成');
        } else {
            $this->warn('⚠️  无法找到路由文件结构，请手动添加路由：');
            $this->line($routeLine);
        }
    }

    /**
     * 自动执行 Seeders
     */
    protected function runSeeders()
    {
        $this->info('🌱 开始执行数据填充...');

        // 执行菜单 Seeder
        $this->runSeeder('PdfMenuSeeder', '菜单数据');

        // 执行数据 Seeder
        $this->runSeeder('PdfDataSeeder', 'PDF图片数据');

        // 执行教材点读数据 Seeder
        $this->runSeeder('TextBookReadDataSeeder', '教材点读数据');
    }

    /**
     * 执行单个 Seeder
     */
    protected function runSeeder($seederClass, $description)
    {
        try {
            $this->info("正在填充 {$description}...");

            $exitCode = Artisan::call('db:seed', [
                '--class' => $seederClass,
                '--force' => true
            ]);

            if ($exitCode === 0) {
                $this->info("✅ {$description}填充完成");

                $output = Artisan::output();
                if ($output) {
                    $this->line($output);
                }
            } else {
                $this->warn("⚠️  {$description}填充可能有问题");
            }

        } catch (\Exception $e) {
            $this->error("❌ {$description}填充失败: " . $e->getMessage());

            if (in_array($seederClass, ['PdfDataSeeder', 'TextBookReadDataSeeder'])) {
                $this->warn('💡 可能是因为缺少源数据连接，你可以稍后手动执行：');
                $this->line("php artisan db:seed --class={$seederClass}");
            }
        }
    }

    protected function showNextSteps()
    {
        $this->line('');
        $this->line('<fg=green>🎉 安装完成！功能已就绪：</>');
        $this->line('✅ 数据表已创建 (pdf_images, pdf_image_coordinates, textbook_reads)');
        $this->line('✅ 模型文件已生成 (PdfImage, PdfImageCoordinate, TextbookRead)');
        $this->line('✅ 管理后台已配置');
        $this->line('✅ 数据库配置已更新');
        $this->line('✅ Category 模型关联关系已更新');
        $this->line('✅ 路由已添加');
        $this->line('✅ 菜单已创建');
        $this->line('✅ 数据已导入');
        $this->line('');
        $this->line('<fg=yellow>📋 可用功能：</>');
        $this->line('• 访问管理后台: 模块管理 -> 教材点读 -> 点读图片');
        $this->line('• 管理点读图片和坐标');
        $this->line('• 管理教材点读内容');
        $this->line('• 支持从 zjmysql 数据库导入数据');
        $this->line('• Category 模型现在支持 PdfImage 关联查询');
        $this->line('');

        if ($this->option('skip-seed')) {
            $this->line('<fg=blue>🔧 手动执行数据填充：</>');
            $this->line('• 导入菜单: <fg=green>php artisan db:seed --class=PdfMenuSeeder</>');
            $this->line('• 导入PDF图片数据: <fg=green>php artisan db:seed --class=PdfDataSeeder</>');
            $this->line('• 导入教材点读数据: <fg=green>php artisan db:seed --class=TextBookReadDataSeeder</>');
            $this->line('');
        }

        $this->line('<fg=blue>🔧 环境变量配置：</>');
        $this->line('请在 .env 文件中添加 zjmysql 数据库配置：');
        $this->line('<fg=green>DB_DATABASE_ZJ=your_zj_database</>');
        $this->line('<fg=green>DB_USERNAME_ZJ=your_zj_username</>');
        $this->line('<fg=green>DB_PASSWORD_ZJ=your_zj_password</>');
        $this->line('');

        $this->line('<fg=blue>🔧 测试关联关系：</>');
        $this->line('• php artisan tinker');
        $this->line('• App\Models\Category\Category::first()->PdfImage');
        $this->line('• App\Models\Pdf\TextbookRead::with("category", "click_learn")->first()');
        $this->line('');

        $this->line('<fg=red>卸载：</>');
        $this->line('如需卸载扩展包，请运行: <fg=red>php artisan rj-pdf:uninstall</>');
    }
}
